package com.dmz.workflow.feign;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.echronos.commons.Result;
import com.echronos.commons.enums.ErrorMsgEnum;
import com.echronos.system.feign.IMemberFeign;
import com.echronos.system.resp.member.MemberSimpleResp;
import com.dmz.workflow.constant.ExceptionMessageConstants;
import com.echronos.workflow.constant.FeignExceptionConstants;
import com.echronos.workflow.constant.ProcessConstants;
import com.dmz.workflow.constant.ProcessDefinitionConstants;
import com.dmz.workflow.dto.ApprovalNode;
import com.dmz.workflow.dto.BranchNode;
import com.dmz.workflow.dto.ConditionOperation;
import com.dmz.workflow.entity.ProcessJson;
import com.dmz.workflow.req.BranchPredictionReq;
import com.dmz.workflow.req.ProcessInstanceReq;
import com.echronos.workflow.req.ProcessStartReq;
import com.echronos.workflow.res.StartProcessRes;
import com.dmz.workflow.service.ProcessDefinitionService;
import com.dmz.workflow.service.ProcessInstanceService;
import com.dmz.workflow.service.WorkflowProcessJsonService;
import com.dmz.workflow.util.ObjectUtils;
import com.dmz.workflow.vo.IntermediateNodeVo;
import com.dmz.workflow.vo.StaffInfoVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.FormService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

@Api
@Slf4j
@RestController
public class ProcessInstanceFeign implements IProcessInstanceFeign {

    @Autowired
    private ProcessDefinitionService processDefinitionService;

    @Autowired
    private ProcessInstanceService processInstanceService;

    @Autowired
    private WorkflowProcessJsonService workflowProcessJsonService;

    @Autowired
    private FormService formService;

    @Autowired
    private IMemberFeign memberFeign;

    @Override
    public Result<StartProcessRes> startProcess(ProcessStartReq processStartReq) {
        Map<String, Object> processInstanceFormData = processStartReq.getProcessInstanceFormData();
        if (ObjectUtils.isEmpty(processInstanceFormData)) {
            return Result.build(ErrorMsgEnum.PARAM_EXCEPTION.getErrorCode(), FeignExceptionConstants.PROCESS_START_PARAM_EMPTY);
        }
        // 1.获取流程节点配置的数据
        ProcessJson processJson = workflowProcessJsonService.getProcessJsonByProcessNameAndCompanyId(processStartReq.getProcessDefinitionName(), processStartReq.getCompanyId());
        if (ObjectUtils.isEmpty(processJson)) {
            return Result.build(ErrorMsgEnum.PARAM_EXCEPTION.getErrorCode(), ExceptionMessageConstants.PROCESS_DEFINITION_INFO_NOT_FOUND);
        }
        String processDefinitionId = processJson.getProcessDefinitionId();
        List<ApprovalNode> approvalNodes = JSON.parseArray(processJson.getProcessJson(), ApprovalNode.class);
        Set<String> keySet = processInstanceFormData.keySet();
        Set<String> formKeys = new HashSet<>();
        for (ApprovalNode approvalNode : approvalNodes) {
            List<BranchNode> conditions = approvalNode.getConditions();
            for (BranchNode condition : conditions) {
                List<ConditionOperation> criteria = condition.getCriteria();
                for (ConditionOperation criterion : criteria) {
                    formKeys.add(criterion.getFormKey());
                }
            }
        }
        // 2.获取启动流程的表单数据
        Object renderedStartForm = formService.getRenderedStartForm(processDefinitionId);
        if (ObjectUtils.isEmpty(renderedStartForm)) {
            return Result.build(ErrorMsgEnum.PARAM_EXCEPTION.getErrorCode(), ErrorMsgEnum.PARAM_EXCEPTION.getMsg());
        }
        Map<String, Object> branchPredictionParams = new HashMap<>();
        JSONArray formComponentArray = JSONObject.parseArray(renderedStartForm.toString());
        JSONArray jsonFormData = new JSONArray();
        for (Object formComponent : formComponentArray) {
            JSONObject jsonObject = JSONObject.parseObject(formComponent.toString());
            // 填充form表单中的数据
            for (String key : keySet) {
                if (key.equals(jsonObject.get("label"))) {
                    jsonObject.put("value", processInstanceFormData.get(key));
                }
            }
            // 获取作为流程条件的表单数据
            for (String formKey : formKeys) {
                if (formKey.equals(jsonObject.get("formKey"))) {
                    branchPredictionParams.put(formKey, jsonObject.get("value"));
                }
            }
            jsonFormData.add(jsonObject);
        }
        // 3.获取流程预判的节点
        BranchPredictionReq branchPredictionReq = new BranchPredictionReq();
        branchPredictionReq.setProcessDefinitionId(processDefinitionId);
        branchPredictionReq.setParameter(branchPredictionParams);
        Result<List<IntermediateNodeVo>> listResult = processDefinitionService.userInputByValue(branchPredictionReq);
        if (ObjectUtils.validateCollectionIsEmpty(listResult.getData())) {
            return Result.build(ErrorMsgEnum.PARAM_EXCEPTION.getErrorCode(), ErrorMsgEnum.PARAM_EXCEPTION.getMsg());
        }
        List<IntermediateNodeVo> listResultDatum = listResult.getData();
        ProcessInstanceReq processInstanceReq = new ProcessInstanceReq();
        for (IntermediateNodeVo intermediateNodeVo : listResultDatum) {
            if (ProcessDefinitionConstants.START_NODE_NAME.equals(intermediateNodeVo.getNodeId())) {
                Result<MemberSimpleResp> memberSimpleRespResult = memberFeign.queryPlatformMember();
                if (ObjectUtils.isNotEmpty(memberSimpleRespResult.getData())) {
                    MemberSimpleResp memberSimpleResp = memberSimpleRespResult.getData();
                    List<StaffInfoVo> staffInfoList = intermediateNodeVo.getStaffInfoList();
                    for (StaffInfoVo staffInfoVo : staffInfoList) {
                        staffInfoVo.setUserId(memberSimpleResp.getUserId());
                        staffInfoVo.setMemberId(memberSimpleResp.getId());
                        processInstanceReq.setMemberId(memberSimpleResp.getId());
                        staffInfoVo.setMemberName(memberSimpleResp.getName());
                    }
                }
            }
        }
        // 4.启动流程
        processInstanceReq.setProcessDefinitionId(processDefinitionId);
        processInstanceReq.setNodesInfo(listResultDatum);
        processInstanceReq.setValues(branchPredictionParams);
        processInstanceReq.setProcessInstanceFormData(jsonFormData.toString());
        processInstanceReq.setProcessInstanceType(ProcessConstants.PROCESS_INSTANCE_CIRCLE_PRICE_TYPE);
        return processInstanceService.startProcess(processInstanceReq);
    }
}
